package com.example.springboottest.aop;

import com.example.springboottest.config.ApiOperation;
import com.example.springboottest.config.LogOperationResp;
import com.example.springboottest.config.OperationType;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Arrays;

@Order(1)
@Slf4j
@Component
@Aspect
//@ConditionalOnProperty(prefix = "web", value = "enable", havingValue = "true")
public class WebLogAspect {

    @Pointcut("execution(public * com.example.springboottest.controller.HelloController.getImage(..))")
//    @Pointcut("execution(* *.*.*.controller.*.*(..))")
    public void getLog(){
        System.out.println("切面拦截校验");
    }

    @Before("getLog()")
    public void doBefore(JoinPoint joinPoint) throws NoSuchMethodException {
        //接受请求，记录内容
        HttpServletRequest request = getHttpServletRequest();
        HttpSession session = request.getSession(true);
        LogOperationResp logOperationResp = getOper(joinPoint);
        // 记录内容
        log.info("开始服务：{}", request.getRequestURI());
        log.info("客户端IP：{}", request.getRemoteAddr());
        log.info("参数值：{}", Arrays.toString(joinPoint.getArgs()));
        log.info("操作类型：{}", logOperationResp.getOperType());
        log.info("操作描述：{}", logOperationResp.getApiOper());
    }

    private static HttpServletRequest getHttpServletRequest() {
        ServletRequestAttributes attributes =
                (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        return request;
    }

    @AfterReturning(returning = "ret", pointcut = "getLog()")
    public void doAfterReturn(JoinPoint joinPoint, String ret) throws NoSuchMethodException {
        LogOperationResp logOperationResp = getOper(joinPoint);
        // 处理返回结果
        log.info("返回值：{}, 操作类型：{}, 操作描述：{}", ret, logOperationResp.getOperType(),
                logOperationResp.getApiOper());
    }

    private LogOperationResp getOper(JoinPoint joinPoint) throws NoSuchMethodException {
        Signature signature = joinPoint.getSignature();
        MethodSignature ms = (MethodSignature) signature;
        Method method1 = joinPoint.getTarget().getClass().getMethod(ms.getName(), ms.getParameterTypes());
//        Method method1 = ms.getMethod();
        OperationType operationType = method1.getAnnotation(OperationType.class);
        String operType = operationType.value();
        ApiOperation apiOperation = method1.getAnnotation(ApiOperation.class);
        String apiOper = apiOperation.value();
        LogOperationResp logOperationResp = new LogOperationResp();
        logOperationResp.setApiOper(apiOper);
        logOperationResp.setOperType(operType);
        return logOperationResp;
    }


}
